/*
 * @Author: 李石
 * @Date: 2024-05-17 14:11:19
 * @LastEditors: lishi
 * @LastEditTime: 2024-05-24 14:09:40
 * @Description: 
 * Copyright (c) 2024 by ${lishi0105@163.com}, All Rights Reserved. 
 */
#ifndef _STREAM_DTO_HPP_
#define _STREAM_DTO_HPP_

#include <iostream>
#include <string>
#include <stdint.h>
#include <unordered_map>
#include <unordered_set>
#include <nlohmann/json.hpp>
#include "BaseDto.hpp"

class StreamAddDto : public BaseDto<StreamAddDto>{
public:
    std::string app;
    std::string stream;
    std::string url;
    int32_t rtp_type;
    // 使用宏定义序列化和反序列化方法
    NLOHMANN_DEFINE_TYPE_INTRUSIVE(StreamAddDto, app, stream, url, rtp_type)
};

class StreamReportDto : public BaseDto<StreamReportDto>{
public:
    std::string app;
    std::string stream;
    std::string url;
    int32_t rtp_type;
    int codec_id = 0;
    bool alive = false;
    std::string play;
    NLOHMANN_DEFINE_TYPE_INTRUSIVE(StreamReportDto, app, stream, url, rtp_type, codec_id, alive, play)
};

class StreamIDDto : public BaseDto<StreamIDDto>{
public:
    std::string app;
    std::string stream;
    NLOHMANN_DEFINE_TYPE_INTRUSIVE(StreamIDDto, app, stream)
};

class StreamDto : public BaseDto<StreamDto>{
public:
    std::string url;
    int rtp_type;
    std::string app;
    std::string stream;
    int codec_id = 0;
    bool alive = false;
    std::string play;
    // 使用宏定义序列化和反序列化方法
    NLOHMANN_DEFINE_TYPE_INTRUSIVE(StreamDto, url, rtp_type, app, stream)
};

class StreamListDto: public BaseDto<StreamListDto>{
public:
    size_t count;
    std::vector<StreamReportDto::Ptr> streams;
public:
    StreamListDto() {
        count = 0;
        streams.clear();
    }
    ~StreamListDto() {
        streams.clear();
    }
    friend void to_json(nlohmann::json& j, const StreamListDto& dto) {
        j = nlohmann::json{{"streams", nlohmann::json::array()}};
        for (const auto& stream : dto.streams) {
            j["streams"].push_back(*stream);
        }
        j["count"] = dto.count;
    }

    // 自定义反序列化方法
    friend void from_json(const nlohmann::json& j, StreamListDto& dto) {
        if (j.contains("streams")) {
            for (const auto& item : j.at("streams")) {
                dto.streams.push_back(std::make_shared<StreamReportDto>(item.get<StreamReportDto>()));
            }
        }
        j.at("count").get_to(dto.count);
    }
}; 

class StreamsInfoDto : public BaseDto<StreamsInfoDto>{
public:
    int count;
    std::unordered_map<std::string, StreamDto::Ptr> streams_by_app_and_stream;
public:
    StreamsInfoDto() {
        count = 0;
        streams_by_app_and_stream.clear();
    }
    ~StreamsInfoDto() {
        streams_by_app_and_stream.clear();
    }
    friend void to_json(nlohmann::json& j, const StreamsInfoDto& dto) {
        j = nlohmann::json{
            {"count", dto.count},
            {"streams_by_app_and_stream", nlohmann::json::object()}
        };

        for (const auto& item : dto.streams_by_app_and_stream) {
            j["streams_by_app_and_stream"][item.first] = *item.second;
        }
    }
    // 自定义反序列化方法
    friend void from_json(const nlohmann::json& j, StreamsInfoDto& dto) {
        j.at("count").get_to(dto.count);

        if (j.contains("streams_by_app_and_stream")) {
            for (const auto& item : j.at("streams_by_app_and_stream").items()) {
                dto.streams_by_app_and_stream.emplace(item.key(), std::make_shared<StreamDto>(item.value().get<StreamDto>()));
            }
        }
    }
};

#endif // _STREAM_DTO_HPP_